package com.redsoft.spirit.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.redsoft.spirit.dao.AccountRepository;
import com.redsoft.spirit.dao.DeptEmpRepository;
import com.redsoft.spirit.dao.RoleAccountRepository;
import com.redsoft.spirit.entity.Account;
import com.redsoft.spirit.entity.DeptEmp;
import com.redsoft.spirit.util.BeanUtils;

/**
 * 后台用户管理的Service
 * 
 * <pre>
 * 后台用户管理的Service
 * </pre>
 * 
 * @author 杨雷
 * @since 1.0
 */
@Service
@Transactional
public class AccountService {

	@Autowired
	private AccountRepository accountRepository;

	@Resource
	private DeptEmpRepository deptEmpRepository;
	
	@Autowired
	private RoleAccountRepository roleAccountRepsitory;

	@Cacheable(value = "user-cache", key = "#userName")
	public List<Account> findUsers(String userName) {
		System.out.println("我没有使用缓存啊啊啊啊啊");
		return accountRepository.findAll();
	}

	/**
	 * 根据userName查询User
	 * 
	 * @return
	 */
	public Map findUsers() {
		System.out.println("我没有使用缓存,我来查询列表");
		Pageable pageable = new PageRequest(0, 2);
		Page users = accountRepository.findAll(pageable);

		Map map = new HashMap<>();
		map.put("total", users.getTotalElements());
		map.put("rows", users.getContent());

		return map;
	}

	/**
	 * 根据条件查询用户信息.
	 * 
	 * <pre>
	 * 根据条件查询用户信息，模糊查询用户的帐号和用户真实姓名
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param offset
	 * @param limit
	 * @param searchKey
	 * @param deptId
	 * @return
	 */
	public HashMap getJsonData(int offset, int limit, String searchKey, String deptId) {
		String sql = "select a.*, sd.name deptName from sys_account a , sys_dept_emp de , sys_department sd where a.id = de.EMP_ID and sd.id=de.DEPT_ID ";
		String countSql = "select count(0) from sys_account a , sys_dept_emp de , sys_department sd where a.id = de.EMP_ID and sd.id=de.DEPT_ID ";

		Map map = new HashMap<>();

		if (searchKey != null) {
			map.put("searchKey", "%" + searchKey + "%");
			sql += " and (a.account_name like :searchKey or a.real_name like :searchKey)";
			countSql += " and (a.account_name like :searchKey or a.real_name like :searchKey)";
		}

		// 不是根部门或者没设置部门
		if (deptId != null && !"1".equals(deptId)) {
			map.put("deptId", deptId);
			sql += " and de.dept_id = :deptId";
			countSql += " and de.dept_id = :deptId";
		}
		sql += " ORDER BY a.create_time desc ";
		return accountRepository.sqlQuery(sql, countSql, map, offset, limit, "total", "rows");
	}

	/**
	 * 保存或者修改user.
	 * 
	 * <pre>
	 * 保存或者修改user，并把当前部门id设置为这个user的部门id
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param user
	 *            用户
	 * @param deptId
	 *            部门ID
	 * @throws Exception
	 */
	public void saveOrUpdate(Account user, String deptId) throws Exception {
		String secretPwd = new Md5Hash(user.getAccountPwd(), "meiyoumima").toString();
		user.setAccountPwd(secretPwd);

		if (!"".equals(user.getId())) {
			Account userTemp = accountRepository.getById(user.getId());
			BeanUtils.copyBeanNotNull2Bean(user, userTemp);
			accountRepository.save(userTemp);
		} else {
			user.setCreateTime(new Date());
			user.setIsActive("1");
			// 后台登录的帐号
			user.setLogonMode(1);
			user = accountRepository.save(user);

			DeptEmp de = new DeptEmp();
			de.setDeptId(deptId);
			de.setEmpId(user.getId());
			deptEmpRepository.save(de);
		}
	}

	/**
	 * 对部门人员关系做修改.
	 * 
	 * <pre>
	 * 对部门人员关系做修改
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param userId
	 * @param deptId
	 */
	public void changeDeptEmp(String userId, String deptId) {
		DeptEmp deptEmp = deptEmpRepository.findByEmpId(userId);

		deptEmp.setDeptId(deptId);
		deptEmpRepository.save(deptEmp);
	}

	/**
	 * 批量删除人员.并从部门关联表中删除掉关系
	 * 
	 * <pre>
	 * 批量删除人员.并从部门关联表中删除掉关系
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param userIds
	 */
	public void deleteUsers(List<String> userIds) {
		accountRepository.deleteUsers(userIds);
		roleAccountRepsitory.deleteRoleUsers(userIds);
		deptEmpRepository.deleteDeptUsers(userIds);
	}
	
	/**
	 * 
	 * 修改密码
	 * <pre>
	 * 修改密码
	 * </pre>
	 * 
	 * @author lixiaodong
	 * @param account
	 * @param newPasswd
	 */
	public void updatePassword(Account account, String newPasswd) {
		account.setAccountPwd(new Md5Hash(newPasswd, "meiyoumima").toString());
		accountRepository.save(account);
	}

	/**
	 * 根据条件查询已经启用的并且不在该角色下的人员.
	 * 
	 * <pre>
	 * 根据角色id查询不在该角色下的，并且已经启用的人员
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param roleId
	 * @param searchKey
	 * @param deptId
	 * @return
	 */
	public List<Account> getUserListByOutRole(String roleId, String searchKey, String deptId) {
		if (deptId != null && !"1".equals(deptId)) {// 不是根部门的查询部门下人员
			return accountRepository.getUserListByOutRoleWithDept(roleId, searchKey, deptId);
		} else {
			// 是根部门的查询所有后台人员
			return accountRepository.getUserListByOutRole(roleId, searchKey);
		}
	}

	/**
	 * 根据条件查询已经启用的并且在该角色下的人员.
	 * 
	 * <pre>
	 * 根据条件查询已经启用的并且在该角色下的人员
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param roleId
	 * @return
	 */
	public List<Account> getUserListByInRole(String roleId) {
		return accountRepository.getUserListByInRole(roleId);
	}

	/**
	 * 根据角色查询该角色下的user.
	 * 
	 * <pre>
	 * 	根据角色查询该角色下的user，带分页功能
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param roleId
	 * @param offset
	 * @param limit
	 * @param searchKey
	 * @return
	 */
	public Map getJsonDataByRole(String roleId, int offset, int limit, String searchKey) {

		String hql = "select a from Account a where a.id in(select ra.accountId from RoleAccount ra where ra.roleId =:roleId)";
		String countHql = "select count(a.id) from Account a where a.id in(select ra.accountId from RoleAccount ra where ra.roleId =:roleId)";

		Map map = new HashMap<>();
		map.put("roleId", roleId);

		if (searchKey != null) {
			map.put("searchKey", "%" + searchKey + "%");
			hql += " and a.accountName like :searchKey";
			countHql += " and a.accountName like :searchKey";
		}
		return accountRepository.retrieve(hql, countHql, map, offset, limit, "total", "rows");
	}

	/**
	 * 根据用户名查询用户.
	 * 
	 * <pre>
	 * 根据用户名查询用户
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param userName
	 * @return
	 */
	public Account getByAccountName(String userName) {
		return accountRepository.getByAccountName(userName);
	}

	/**
	 * APP用户注册方法.
	 * 
	 * <pre>
	 * APP用户注册，会在account表中插入数据，并在部门关联表中插入数据，由于需要激活，所以account的isActive设置为0，未激活
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param account
	 * @param deptId
	 * @return
	 */
	public Account register(Account account, String deptId) {
		String secretPwd = new Md5Hash(account.getAccountPwd(), "meiyoumima").toString();
		account.setAccountPwd(secretPwd);
		account.setIsActive("0");

		account = accountRepository.save(account);

		DeptEmp de = new DeptEmp();
		de.setDeptId(deptId);
		de.setEmpId(account.getId());

		deptEmpRepository.save(de);
		return account;
	}

	/**
	 * 审核通过申请的员工.
	 * 
	 * <pre>
	 * 审核通过申请的员工
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param userId
	 */
	public void approve(String userId) {
		Account account = accountRepository.getById(userId);
		account.setIsActive("1");
		accountRepository.save(account);
	}

	/**
	 * 修改人员状态.
	 * 
	 * <pre>
	 * 修改人员状态.
	 * </pre>
	 * 
	 * @author 杨雷
	 * @param userId
	 * @param isActive
	 */
	public void update(String userId, String isActive) {
		Account account = accountRepository.getById(userId);
		account.setIsActive(isActive);
		accountRepository.save(account);
	}

	/**
	 * 将登录人手机型号/设备token(华为)保存到数据库
	 * 
	 * <pre>
	 *  将登录人手机型号/设备token(华为)保存到数据库
	 * </pre>
	 * 
	 * @author 李晓东
	 * @param accountName
	 * @param extA
	 * @param extB
	 */
	public void updateLogin(String accountName, String extA, String extB) {
		/*
		 * 如果上传了deviceToken，将原来帐号保存的deviceToken清除，
		 * 重新赋值给另一个帐号，保证华为推送的token一个帐号只能有一个，token不能重复
		 */
		if (extB != null && !"".equals(extB)) {
			accountRepository.updateDeviceToken(extB);
		}
		Account account = accountRepository.getByAccountName(accountName);
		account.setExtA(extA);
		account.setExtB(extB);
		accountRepository.save(account);
	}
	
	/**
	 * 
	 * 获取账户详情
	 * <pre>
	 * 获取账户详情
	 * </pre>
	 * 
	 * @author lixiaodong
	 * @param userId
	 * @return
	 */
	public Account getById(String userId) {
		String sql = "select sa.*, sd.name deptName "
				+ " from sys_account sa "
				+ " left join sys_dept_emp sde "
				+ " on sde.emp_id = sa.id "
				+ " left join sys_department sd "
				+ " on sde.dept_id = sd.id "
				+ " where 1=1 and sa.id = ? ";
		List<Account> accountList = accountRepository.sqlQuery(sql, userId);
		
		if (accountList.size() > 0 && !accountList.isEmpty()) {
			
			return accountList.get(0);
		}
		
		return null;
	}
}
